using System;
using System.IO;
using System.Diagnostics;
using System.Threading;
using Microsoft.ApplicationBlocks.Updater;

namespace MSIProcessor
{
	/// <summary>
	/// Summary description for LaunchStub.
	/// </summary>
	class LaunchStub
	{
		private bool manifestDownloaded = false;
		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main(string[] args)
		{
			LaunchStub launch = new LaunchStub();
			launch.CheckAndUpdate(); 
		}

		LaunchStub()
		{
		}
		private void CheckAndUpdate()
		{
			try
			{
				ApplicationUpdaterManager updater = ApplicationUpdaterManager.GetUpdater();
				Manifest[] manifests = updater.CheckForUpdates();
				if ( manifests.Length > 0 )
				{
					// Here we are showcasing the included manifest functionality as well but
					// as the manifests are for Install, Update and Uninstall, we should apply 
					// only one manifest at a time, also as the order is same as described above
					// apply always the first manifest, so first time the application will be 
					// installed, second time the application will be updated and third time the 
					// application will be uninstalled.

					manifests[0].Apply = true;
					
					// subscribe to various events.
					updater.DownloadStarted += new DownloadStartedEventHandler(updater_DownloadStarted);
					updater.DownloadProgress += new DownloadProgressEventHandler(updater_DownloadProgress);
					updater.DownloadError += new DownloadErrorEventHandler(updater_DownloadError);
					updater.DownloadCompleted += new DownloadCompletedEventHandler(ApplicationUpdater_DownloadCompleted);
					updater.ActivationStarted += new ActivationStartedEventHandler(updater_ActivationStarted);
					updater.ActivationInitializing += new ActivationInitializingEventHandler(updater_ActivationInitializing);
					updater.ActivationInitializationAborted += new ActivationInitializationAbortedEventHandler(updater_ActivationInitializationAborted);
					updater.ActivationError += new ActivationErrorEventHandler(updater_ActivationError);
					updater.ActivationCompleted += new ActivationCompletedEventHandler(updater_ActivationCompleted);
				
					updater.Download( manifests, TimeSpan.MaxValue);
					
					// we are applying only one manifest at a time 
					// hence just check the if the manifest has been correctly 
					// downloaded.

					if(manifestDownloaded)
					{
						updater.Activate(manifests);
						manifestDownloaded = false;
					}
				}

				//Start the installed / updated application.
				string appInfo = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
				appInfo += @"\UpdaterQuickStarts\SimpleApplication\SimpleApplication.exe";
				if(File.Exists(appInfo) && manifests.Length > 1)
				{
					ProcessStartInfo psi = new ProcessStartInfo(appInfo);
					Process.Start( psi );
				}
				else
				{
					Console.WriteLine("The Application has been uninstalled. Check Add/Remove Programs.");
				}
			}
			catch(Exception ex)
			{
				Console.WriteLine(string.Format("Following error has occured: {0}",ex.Message)); 
			}

			Console.WriteLine("Hit ENTER to end.");
			Console.ReadLine();
		}

		private void ApplicationUpdater_DownloadCompleted( object sender, ManifestEventArgs e)
		{
			Console.WriteLine( "Download Complete : {0}", e.Manifest.ManifestId );
			manifestDownloaded = true;
		}

		private void updater_ActivationCompleted( object sender, ActivationCompleteEventArgs e )
		{
			Console.WriteLine( "Activation Complete : {0}", e.Manifest.ManifestId );
		}

		private void updater_DownloadError(object sender, ManifestErrorEventArgs e)
		{
			Console.WriteLine( "Download Error : {0}", e.Manifest.ManifestId );
		}

		private void updater_DownloadProgress(object sender, DownloadProgressEventArgs e)
		{
			Console.WriteLine( "Download Progress for manifest: "+ e.Manifest.ManifestId +
				"- Files: "+e.FilesTransferred+"/"+e.FilesTotal+
				" - Bytes: "+e.BytesTransferred+"/"+e.BytesTotal);

		}

		private void updater_DownloadStarted(object sender, DownloadStartedEventArgs e)
		{
			Console.WriteLine( "Download Started : {0}", e.Manifest.ManifestId );	
		}

		private void updater_ActivationError(object sender, ManifestErrorEventArgs e)
		{
			Console.WriteLine( "Activation Error : {0}", e.Manifest.ManifestId );
		}

		private void updater_ActivationInitializationAborted(object sender, ManifestEventArgs e)
		{
			Console.WriteLine( "Activation Initialization Aborted : {0}", e.Manifest.ManifestId );
		}

		private void updater_ActivationInitializing(object sender, ManifestEventArgs e)
		{
			Console.WriteLine( "Activation Initializing : {0}", e.Manifest.ManifestId );
		}

		private void updater_ActivationStarted(object sender, ManifestEventArgs e)
		{
			Console.WriteLine( "Activation Started : {0}", e.Manifest.ManifestId );
		}
	}
}
